home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / quicktime / basics / moviegworlds / trackgworlds.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  11.0 KB  |  314 lines

  1. /*
  2.     File:        TrackGWorlds.c
  3.  
  4.     Contains:    
  5.  
  6.     Written by:     
  7.  
  8.     Copyright:    Copyright © 1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 8/17/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */// INCLUDES
  23. #include "TrackGWorlds.h"
  24. #include <Fonts.h>
  25.  
  26. // GLOBALS
  27. Movie                     gMovie = NULL;
  28. CWindowPtr                 gWindow = NULL;
  29.  
  30. Rect                        gMovieRect = {0, 0, 0, 0};
  31. GWorldPtr                    gTrackGWorld = NULL;            // Note that in a real program this handle should be purged later if not used.
  32. GDHandle                    gTrackGDevice =  NULL;
  33. GWorldPtr                    gComposeGWorld = NULL;            // Note that in a real program this handle should be purged later if not used.
  34. GDHandle                    gComposeGDevice =  NULL;
  35.  
  36. TimeValue                    gMovieDuration = 0L;
  37. long                        gTickCount = 0L;
  38. long                        gSampleCount = 0L;
  39. Rect                        gTimeDurationRect = { 5, 5, 10 ,110};
  40.  
  41.  
  42. // ______________________________________________________________________
  43. //•  MAIN -- Starting point.
  44. void main(void) {
  45.     EventRecord     anEvent;
  46.     OSErr        anErr = noErr;
  47.     OSType        mediaType = VideoMediaType;
  48.     
  49.     //• Initialize the needed parts.
  50.     InitMacEnvironment(6);
  51.     InitializeQTEnvironment();
  52.     if ( InitializeMovie() != noErr ) ExitToShell();        // we had problems with the movie.
  53.  
  54.     //• Draw basic strings inside the window.
  55.     DrawFpsStats(0L); 
  56.     DrawMovieFpsStats();
  57.     DrawUsageInformation();
  58.     
  59.     //• Event loop.
  60.     for(;;) {
  61.         WaitNextEvent(everyEvent, &anEvent, 60, NULL);
  62.         
  63.         if(anEvent.what == mouseDown)
  64.             break;
  65.         
  66.         if(anEvent.what == keyDown) {        
  67.             SetGWorld(gWindow, NULL);
  68.             SetMovieGWorld(gMovie, (CGrafPtr)gWindow, NULL);
  69.             GoToBeginningOfMovie(gMovie); 
  70.             StartMovie(gMovie); 
  71.             
  72.             gTickCount = TickCount();
  73.             gSampleCount = 1L;
  74.             do {
  75.                 MoviesTask(gMovie, 0);
  76.             }
  77.             while (IsMovieDone(gMovie) == false);
  78.             
  79.             gTickCount = TickCount() - gTickCount;
  80.             DrawFpsStats(gTickCount);
  81.             QTUDrawVideoFrameAtTime(gMovie, GetMovieTime(gMovie, NULL));  // nudge one last time to make sure last frame is drawn.
  82.         }
  83.     }
  84. }
  85.  
  86. // ______________________________________________________________________
  87. //• InitMacEnvironment -- Initialize the Mac Toolbox.
  88. void InitMacEnvironment(long nMasters) {
  89.     long i;
  90.  
  91.     MaxApplZone();
  92.     
  93.     for(i = 0; i <nMasters; i++)
  94.         MoreMasters();
  95.     
  96.     InitGraf(&qd.thePort);
  97.     InitFonts();
  98.     InitWindows();
  99.     InitMenus();
  100.     FlushEvents(everyEvent, 0);
  101.     TEInit();
  102.     InitCursor();
  103.     InitDialogs(NULL);
  104. }
  105.  
  106.  
  107. // ______________________________________________________________________
  108. //• InitializeQTEnvironment -- Initialize the QuickTime movie toolbox parts.
  109. void InitializeQTEnvironment(void) {
  110.     OSErr anErr = noErr;
  111.     
  112.     if( !QTUIsQuickTimeInstalled() ) {
  113.         DebugStr("\pThe QuickTime extension is not present in this system");
  114.         ExitToShell();
  115.     }
  116.  
  117.     if( (QTUGetQTVersion() >> 16 ) < 0x200 ) {
  118.         DebugStr("\pWe need QT 2.0 or higher due to APIs used in this sample, consult the sources (exit).");
  119.         ExitToShell();
  120.     }
  121.     
  122. #if powerc    
  123.     if( !QTUIsQuickTimeCFMInstalled() ) {
  124.         DebugStr("\pThe QuickTime PowerPlug extension is not available (exit)");
  125.         ExitToShell();    
  126.     }                            
  127. #endif 
  128.     
  129.     anErr = EnterMovies(); DebugAssert(anErr == noErr);
  130.     if(anErr != noErr) {
  131.         DebugStr("\pProblems with Entermovies, returning errors (exit)");
  132.         ExitToShell();
  133.     }
  134. }
  135.  
  136.  
  137. // ______________________________________________________________________
  138. //• InitializeMovie -- Initialize needed movie parts for the offscreen handling.
  139. OSErr InitializeMovie(void) {
  140.     OSErr         anErr = noErr;
  141.     Rect             windowBounds = { kWindowYStart, kWindowXStart, kWindowHeigth, kWindowLength};
  142.     Track        firstVideoTrack = NULL;
  143.     Media        firstVideoMedia = NULL;
  144.     short        mediaPixelDepth = 0;
  145.     short        monitorPixelDepth = 0;
  146.     Rect            trackRect = {0, 0, 0, 0};
  147.     CGrafPtr        aSavedPort = NULL;
  148.     GDHandle        aSavedGDevice = NULL;
  149.     CTabHandle    colorTable = NULL;
  150.     long            seed = 0L;
  151.     
  152.     //• Create the window we will use.
  153.     gWindow = (CWindowPtr) NewCWindow(NULL, &windowBounds, "\pTrack GWorld Test", true, noGrowDocProc,
  154.                                             NULL, false, 0); DebugAssert(gWindow != NULL);
  155.     SetPort((GrafPtr)gWindow);
  156.     GetGWorld(&aSavedPort, &aSavedGDevice);
  157.  
  158.     //• Get the movie.
  159.     anErr = QTUSimpleGetMovie(&gMovie); DebugAssert(anErr == noErr);
  160.     if(anErr) goto Closure;
  161.     
  162.     //• Adjust the movie box values.
  163.     GetMovieBox(gMovie, &gMovieRect); 
  164.     OffsetRect(&gMovieRect,  -gMovieRect.left,  -gMovieRect.top);
  165.     SetMovieBox(gMovie, &gMovieRect); 
  166.     AlignWindow((WindowPtr)gWindow, false,  &gMovieRect, NULL);
  167.  
  168.     //• Specify the Movie GWorld.
  169.     SetMovieGWorld(gMovie, (GWorldPtr)gWindow, NULL);
  170.     anErr = GetMoviesError(); DebugAssert(anErr == noErr); if(anErr) goto Closure;
  171.     
  172.     //• Get movie duration.
  173.     gMovieDuration = GetMovieDuration(gMovie);
  174.     
  175.     //•  Find first video track, track dimensions, pixel depth and so on (need that for the GWorld creation later).
  176.     firstVideoTrack = GetMovieIndTrackType(gMovie, 1, VideoMediaType, movieTrackMediaType); // Assume we have 2.0 installed (GetMovieINdaTrackType).
  177.     anErr = GetMoviesError(); DebugAssert(anErr == noErr); if(anErr || firstVideoTrack == NULL) goto Closure;
  178.     
  179.     anErr = QTUGetTrackRect(firstVideoTrack, &trackRect); DebugAssert(anErr == noErr);
  180.     firstVideoMedia = GetTrackMedia(firstVideoTrack); DebugAssert(firstVideoMedia != NULL);
  181.     mediaPixelDepth = QTUGetVideoMediaPixelDepth(firstVideoMedia, 1);
  182.     monitorPixelDepth = (**(**aSavedGDevice).gdPMap).pixelSize;
  183.     colorTable = (**(**aSavedGDevice).gdPMap).pmTable;
  184.     
  185.     // As we copy the whole colorTable, we don't need to worry about the ctSeed values, they are the same for all
  186.     // three GWorlds now. We yank out the value just to show how it's done, anyway...
  187.     seed = (**colorTable).ctSeed;
  188.     
  189.     //• Create our Track GWorlds (note that monitorDepth == 0 implies default monitor depth).
  190.     // If we would use initial GWorld pixmap for something, then it also makes sense to EraseRect the contents.
  191.     anErr = NewGWorld(&gTrackGWorld, monitorPixelDepth, &gMovieRect, colorTable, gTrackGDevice, 0); DebugAssert (anErr == noErr);
  192.     if(anErr) goto Closure;
  193.  
  194.     anErr = NewGWorld(&gComposeGWorld, monitorPixelDepth, &gMovieRect, colorTable, gComposeGDevice, 0); DebugAssert (anErr == noErr);
  195.     if(anErr) goto Closure;
  196.     // anErr = NewGWorld(&gTrackGWorld, mediaPixelDepth, &gMovieRect, NULL, gTrackGDevice, 0); DebugAssert (anErr == noErr);
  197.     
  198.     //• Put together our Track GWorld environment.
  199.     SetTrackGWorld(firstVideoTrack, (CGrafPtr)gTrackGWorld, gTrackGDevice, NewTrackTransferProc(MyTrackTransferProc), 0L);
  200.     
  201.     //• The following commented line could be used if we want the track transfer proc to trigger, but no redirection of the track GWorld.
  202.      // SetTrackGWorld(firstVideoTrack, NULL, NULL, NewTrackTransferProc(MyTrackTransferProc), 0L);
  203.     anErr = GetMoviesError(); DebugAssert(anErr == noErr); if(anErr) goto Closure;
  204.     
  205.     //• Update the movie so that the first frame is drawn.
  206.     anErr = QTUDrawVideoFrameAtTime(gMovie, 0L); DebugAssert(anErr == noErr);
  207.     
  208. Closure:
  209.     return anErr;
  210. }
  211.  
  212. // ______________________________________________________________________
  213. //• MyTrackTransferProc -- Callback called when movie toolbox draws to GWorld.
  214. pascal OSErr MyTrackTransferProc(Track /*theTrack*/, long /*refCon*/) {
  215.     OSErr             anErr = noErr;
  216.     PixMapHandle        trackPixMap = NULL;
  217.     PixMapHandle        composePixMap = NULL;
  218.     CGrafPtr            aSavedPort = NULL;
  219.     GDHandle            aSavedGDevice = NULL;
  220.     Str255            tempString;
  221.     long                percentage = 0L;
  222.     Rect                eraseRect = { 12 ,4, 20, 35};
  223.     
  224.     //• Bounce the sample code (needed for later statistics).
  225.     gSampleCount++;
  226.     
  227.     //• Get and lock the GWorld pixmaps.
  228.     trackPixMap = GetGWorldPixMap( (GWorldPtr)gTrackGWorld);  
  229.     if(!LockPixels(trackPixMap)) goto Closure;
  230.     
  231.     composePixMap = GetGWorldPixMap( (GWorldPtr)gComposeGWorld);  
  232.     if(!LockPixels(composePixMap)) goto Closure;
  233.     
  234.     //• Switch over to the compose GWorld  for CopyBits (the actual GWorld is already set to the correct destination (movie GWorld)). 
  235.     GetGWorld(&aSavedPort, &aSavedGDevice);  SetGWorld( (CGrafPtr)gComposeGWorld, NULL);
  236.  
  237.     //• Blit from Track GWorld into the compose GWorld.
  238.     ForeColor(blackColor); BackColor(whiteColor); 
  239.     
  240.     CopyBits( (BitMap *) *trackPixMap, (BitMap *) *composePixMap, &gMovieRect, &gMovieRect,
  241.                     srcCopy, NULL );            
  242.  
  243.     //• Draw progress bar into the compose GWorld.
  244.     PenSize(1,1); ForeColor(whiteColor); FrameRect(&gTimeDurationRect);
  245.     percentage = 100L * GetMovieTime(gMovie, NULL) / gMovieDuration;
  246.     MoveTo(5,5); ForeColor(yellowColor); PenSize(4,4); LineTo( percentage +5L, 5); 
  247.  
  248.     //• Draw percentage numbers into the main GWorld (window).
  249.     MoveTo(5,20); TextFace(bold); TextSize(9); ForeColor(redColor); 
  250.     NumToString(percentage, tempString);  DrawString(tempString); 
  251.     MoveTo(25,20); DrawString("\p%");
  252.     
  253.     //• Blit from the composite GWorld into the main screen.
  254.     SetGWorld( (CGrafPtr)gWindow, NULL);
  255.     ForeColor(blackColor); BackColor(whiteColor); 
  256.     
  257.     CopyBits( (BitMap *) *composePixMap, (BitMap *) &gWindow->portPixMap, &gMovieRect,
  258.                     &gMovieRect, srcCopy, NULL );       // blit from offscreen bitmap to movie track pixmap
  259.  
  260.     //• Restore GWorlds, unlock offscreen GWorld pixels.
  261.     SetGWorld(aSavedPort, aSavedGDevice);
  262.     UnlockPixels(trackPixMap);  UnlockPixels(composePixMap); 
  263.  
  264. Closure:
  265.     return anErr;
  266. }
  267.  
  268.  
  269. // ______________________________________________________________________
  270. //• DrawFpsStats -- Provide and draw statistics concerning how many frames were drawn per second.
  271. void DrawFpsStats(long tickCount){
  272.     Str255     theString;
  273.     Rect        eraseArea = {kDrawValuesY-20, kDrawValuesX -20, kDrawValuesY+20, kDrawValuesX+20};
  274.  
  275.     EraseRect(&eraseArea); 
  276.     
  277.     //• Display the fps values.
  278.     MoveTo(kDrawTextX, kDrawTextY); 
  279.     TextFace(bold); TextSize(9);
  280.     DrawString("\pFrames drawn/second:");
  281.     if(tickCount != 0L) {
  282.         MoveTo(kDrawValuesX, kDrawValuesY);
  283.         NumToString( (60L * gSampleCount/tickCount), theString); 
  284.         DrawString(theString);
  285.     }
  286. }
  287.  
  288.  
  289. // ______________________________________________________________________
  290. //• DrawMovieFpsStats -- Get the statistics from the movie concerning frames per second, draw this.
  291. void DrawMovieFpsStats(void) {
  292.     Str255    theString;
  293.     long        nFrames = 0L;
  294.     long        nSeconds = 0L;
  295.     
  296.     MoveTo(kDrawTextX, kDrawTextY+40);
  297.     TextFace(bold); TextSize(9);
  298.     DrawString("\pMovie stats, fps: ");
  299.     MoveTo(kDrawValuesX, kDrawValuesY + 40);
  300.  
  301.     nFrames =  gMovieDuration / QTUGetDurationOfFirstMovieSample(gMovie, VideoMediaType);
  302.     nSeconds = gMovieDuration / GetMovieTimeScale(gMovie);
  303.     NumToString( (nFrames/nSeconds), theString);
  304.     DrawString(theString);
  305. }
  306.  
  307. // ______________________________________________________________________
  308. //• DrawUsageInformation -- Draw instructions how to use this simple program.
  309. void DrawUsageInformation(void) {
  310.     TextFace(normal); TextSize(9);
  311.     MoveTo(kDrawTextX, 200); DrawString("\pHit a key to start the movie.");
  312.     MoveTo(kDrawTextX, 220); DrawString("\pClick on the mouse to terminate program.");
  313. }
  314.